using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;

namespace Commons.Utils
{
	public class MapperUtils
	{
		public static int[] GetCommaSeparatedIntegers(string csv)
		{
			if (csv == null || csv.Trim().Length == 0)
			{
				return new int[] {};
			}

			return SplitInt(csv);
		}

		private static int[] SplitInt(string str)
		{
			List<int> l = new List<int> ();

			foreach(string token in str.Split(','))
			{
				l.Add(int.Parse(token.Trim()));
			}
			return l.ToArray ();
		}

		private static string[] SplitString(string str)
		{
			List<string> l = new List<string> ();
			
			foreach(string token in str.Split(','))
			{
				l.Add(token.Trim());
			}
			return l.ToArray ();
		}


		private static Type[] SplitType(string str)
		{
			List<Type> l = new List<Type>();
			
			foreach(string token in str.Split(','))
			{
				string className = token.Trim();
				Type t = ReflectionHelper.GetCustomType(className);
				if (t == null)
				{
					throw new ArgumentException("Cannot find type "+className, "type");
				}
				l.Add(t);
			}
			return l.ToArray ();
		}

		public static string[] GetCommaSeparatedStrings(string csv)
		{
			if (csv == null || csv.Trim().Length == 0)
			{
				return new string[] {};
			}

			return SplitString(csv);
		}

		public static string[] GetCommaSeparatedLowerStrings(string csv)
		{
			if (csv == null || csv.Trim().Length == 0)
			{
				return new string[] {};
			}

			return SplitString (csv.ToLower ());
		}

		public static Type[] GetCommaSeparatedTypes(string csv)
		{
			if (csv == null || csv.Trim().Length == 0)
			{
				return new Type[] {};
			}

			return SplitType(csv);
		}

		public static int Count(IEnumerable source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			
			// Optimization for ICollection implementations (e.g. arrays, ArrayList)
			ICollection collection = source as ICollection;
			if (collection != null)
			{
				return collection.Count;
			}
			
			IEnumerator iterator = source.GetEnumerator();
			try
			{
				int count = 0;
				while (iterator.MoveNext())
				{
					count++;
				}
				return count;
			}
			finally
			{
				IDisposable disposable = iterator as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
		}
	}
}

